﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using Ongoal.Quotation.Common.Enum;
using Org.BouncyCastle.Asn1.X509;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Ongoal.Quotation
{
    /// <summary>
    /// API 返回结果
    /// </summary>
    public class ApiResultAttribute : ActionFilterAttribute
    {
        private bool _IsDefault = true;

        /// <summary>
        /// 构造函数
        /// </summary>
        public ApiResultAttribute()
        {
            this._IsDefault = false;
        }

        /// <summary>
        /// 重载执行函数
        /// </summary>
        /// <param name="context"></param>
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            var apiresult = context.Filters.Where(x => x is ApiResultAttribute).Select(x => (x as ApiResultAttribute)).ToList().Select(x => x.Order).ToList();
            if (apiresult.Count > 1 && this._IsDefault)
            {
                base.OnResultExecuting(context);
                return;
            }
            if (context.HttpContext.Request.Headers.ContainsKey("Accept"))
            {
                context.HttpContext.Request.Headers["Accept"] = "application/json";
            }
            else
            {
                context.HttpContext.Request.Headers.Add("Accept", "application/json");
            }
            if (context.Result is ObjectResult)
            {
                var objectResult = context.Result as ObjectResult;
                if (context.Result is BadRequestObjectResult)
                {
                    BadRequestObjectResult temp = (BadRequestObjectResult)objectResult;
                    context.Result = new ObjectResult(new ApiResult() { status = temp.StatusCode.HasValue ? temp.StatusCode.Value : (int)StatusCodeEnum.Status1001ParameterError, msg = "请求参数异常", data = temp.Value });
                }
                else if (objectResult != null && objectResult.DeclaredType != null && objectResult.DeclaredType.IsAssignableTo(typeof(ApiResultBase)))
                {
                    //API返回ApiResult实体，无需多包一层
                }
                else
                {
                    if (objectResult == null || objectResult.Value == null)
                    {
                        context.Result = new ObjectResult(new ApiResult() { status = (int)StatusCodeEnum.Status404NotFound, msg = "未找到资源" });
                    }
                    else
                    {
                        if (context.Result.GetType() == typeof(ObjectResult) || objectResult.StatusCode == (int)StatusCodeEnum.Status200OK)
                        {
                            context.Result = new ObjectResult(new ApiResult() { msg = "", data = objectResult.Value });
                        }
                        else
                        {
                            context.Result = new ObjectResult(new ApiResult() { status = objectResult.StatusCode.HasValue ? objectResult.StatusCode.Value : (int)StatusCodeEnum.Status200OK, msg = GetObjectResultMessage(objectResult.Value), data = objectResult.Value });
                        }

                    }
                }
            }
            else if (context.Result is EmptyResult)
            {
                context.Result = new ObjectResult(new ApiResult() { data = null });
            }
            else if (context.Result is ContentResult)
            {
                context.Result = new ObjectResult(new ApiResult() { data = (context.Result as ContentResult).Content });
            }
            else if (context.Result is StatusCodeResult)
            {
                context.Result = new ObjectResult(new ApiResult() { status = (context.Result as StatusCodeResult).StatusCode, data = null });
            }
        }
        private string? GetObjectResultMessage(object? obj)
        {
            if (obj == null)
            {
                return "";
            }
            var targetType = obj.GetType();
            var property = targetType.GetProperties().FirstOrDefault(p => p.Name == "Title");
            if (property != null && property.GetMethod != null)
            {
                return property.GetValue(obj) as string;
            }
            return "";
        }
    }

}
